package com.scalar.chiptrack.adaptor.sitime;

import com.scalar.chiptrack.jobs.JobHandler;
import com.scalar.chiptrack.adaptor.AdaptorConstants;
import com.scalar.chiptrack.adaptor.AdaptorUtils;
import com.scalar.chiptrack.adaptor.FabSortLot;
import com.scalar.chiptrack.adaptor.dao.FabSortAdaptorDAO;
import com.scalar.chiptrack.adaptor.dao.AdaptorRunInfo;
import com.scalar.chiptrack.utils.Logger;
import com.scalar.ScalarException;

import java.util.HashMap;
import java.util.ArrayList;
import java.util.Iterator;
import java.io.File;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

/**
 * Created by IntelliJ IDEA.
 * User: munugoti
 * Date: 8 Jan, 2010
 * Time: 5:29:09 PM
 */
public class SiTimeFTPDataParser extends JobHandler implements AdaptorConstants
{
    private HashMap<String, FabSortLot> m_sortBinDataMap    = new HashMap<String, FabSortLot>();
    private HashMap<String, FabSortLot> m_sortTotalMap      = new HashMap<String, FabSortLot>();
    ArrayList<FabSortLot> sortlotbinList = new ArrayList<FabSortLot>();
    private Logger m_parserLogger = null;
    private String m_dataOutputDir = null;

    public SiTimeFTPDataParser() throws ScalarException
    {
        try
        {
            m_dataOutputDir = AdaptorUtils.getDataOutputDir(VENDOR_NAME_SITIME , WIP_TYPE_SORT);
            AdaptorUtils.makeAllAdaptorDirs(m_dataOutputDir);
            m_parserLogger = AdaptorUtils.getDataParserLogger(m_dataOutputDir,VENDOR_NAME_SITIME);
            FabSortAdaptorDAO.setLogger(m_parserLogger);
            AdaptorUtils.setLogger( m_parserLogger );
        }
        catch ( ScalarException se )
        {
            System.out.println( "ERROR!! ERROR!! ERROR!! Could not create get the logger to log SiTime FTP Data Parser activity, Exception: " + se );
            throw se;
        }
    }

    public static void main( String args[] ) throws Exception
    {
        try
        {
            new SiTimeFTPDataParser().execute();
        }
        catch ( Exception e )
        {
            throw e;
        }
    }

    public void execute() throws Exception
    {
        AdaptorUtils.printHeader( VENDOR_NAME_SITIME + " SORT FTP", CONSTANT_PARSER );

        File doneDestDir = new File(m_dataOutputDir + "/done");

        File wipDataoutDir = new File(m_dataOutputDir);

        File[] fileList = wipDataoutDir.listFiles();

        if ((fileList == null) || (fileList.length <= 3))
        {
           log("No file found in directory: " + wipDataoutDir);
           throw new ScalarException("No file found in directory: " + wipDataoutDir + "----\n\n");
        }

        int adaptor_id = AdaptorRunInfo.getLastRunAdaptorId( SiTimeFTPAdaptor.ADAPTOR_NAME, CONSTANT_ADAPTOR);

        ArrayList<File> successFileList   = new ArrayList<File>();
        boolean success             = false;

        for (int i = 0; i < fileList.length; i++)
        {
            if ( fileList[i].isDirectory() )
            {
                continue;
            }

            try
            {
                // Step 1
                // Parse Files to get Object List
                if ( fileList[i].getName().startsWith( SiTimeFTPAdaptor.FILE_NAME_SORT_WIP ) )
                {
                    sortlotbinList = parseSortLotBinReport( fileList[i].getAbsolutePath() );

                    successFileList.add( fileList[i] );
                }
                success = true;
            }
            catch ( Exception e )
            {
                AdaptorRunInfo.updatedAdaptorStatus( CONSTANT_FAILURE, adaptor_id );
                success = false;
                log( "Exception while parsing and storing file: " + fileList[i].getAbsolutePath() + "\nException: " + e );
                e.printStackTrace();
                throw e;
            }
        }

        //To get the Sort Binning information
        //getSortBinDetails( sortlotbinList );

        getSortBinDataMap( sortlotbinList );

        try
        {
            if ( m_sortBinDataMap.isEmpty() == false )
            {
                FabSortAdaptorDAO.saveSortBinData( null, m_sortBinDataMap.values().iterator() );
            }
            success = true;
            m_sortBinDataMap.clear();
        }
        catch(Exception e)
        {
            AdaptorRunInfo.updatedAdaptorStatus( CONSTANT_FAILURE, adaptor_id );
            success = false;
            System.out.println(" Exception Occrred While Saving the Sort Binning Info " +e );
            throw e;
        }

       // Update Adaptor_Run_Info table
        try
        {
            if ( success )
            {
                AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, SiTimeFTPAdaptor.ADAPTOR_NAME, CONSTANT_SUCCESS, adaptor_id);
                System.out.println( "SUCCESSFULLY UPDATED IN THE DATABASE" );
            }
        }
        catch ( ScalarException se )
        {
            success = false; //As filES DATA SAVED , UPDATEING AS SUCCESS
            AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, SiTimeFTPAdaptor.ADAPTOR_NAME, CONSTANT_SUCCESS, adaptor_id);
            log( "WARNING!! WARNING!! WARNING!! Could not update Adaptor run information, Exception: " + se );
            throw se;
        }

       // Move the successful files to 'done' directory
       if ( success )
       {
           AdaptorUtils.moveFilesToDone( successFileList, doneDestDir );
       }
    } // end of execute method.


    /**
     * Reads, parses the file
     */
    private ArrayList<FabSortLot> parseSortLotBinReport( String fileName ) throws Exception
    {
        FabSortLot sortBinReport = null;
        if ( fileName == null ) throw new ScalarException( "Filename argument is null" );

        // Phase-I variables
        File lotbinFile = new File( fileName );
        if ( lotbinFile.exists() == false )
        {
            throw new ScalarException( fileName + " doesnt exist" );
        }

        String LOTNO    = "LOT_ID =";
        String WAFERID  = "WAFER_ID =";
        String deviceName = "M101-FW";
        String lotNo = null;
        int waferNo = 0;
        int goodDieQtyIn = 0;
        int totalDieQtyIn = 0;
        String line = null;

        BufferedReader bReader = null;
        try
        {
            bReader = new BufferedReader( new FileReader( lotbinFile ) );
            sortBinReport = new FabSortLot();

            while ( ( line = bReader.readLine() ) != null  )
            {
                line = line.trim();
                if ( line.startsWith( "MAP =" ) )
                {
                    //System.out.println("line = " + line);
                    break;
                }
                if ( line.length() < 65 )
                {
                    line = line.replaceAll("\"","");
                    /*if ( line.indexOf( LOTNO ) != -1 )
                    {
                        lotNo = line.substring( LOTNO.length() ).trim();
                       System.out.println("lotNo = " + lotNo);
                    }*/
                    if ( line.indexOf( WAFERID ) != -1 )
                    {
                        int index = line.indexOf("-");
                        lotNo = line.substring( WAFERID.length() ).trim();
                        waferNo = Integer.parseInt(line.substring( index+1, index + 3 ).trim() );
                        //System.out.println("waferNo = " + waferNo);
                        //System.out.println("lotNo = " + lotNo);
                    }
                    if ( !line.startsWith("REF") && line.indexOf( "DIES =" ) != -1 )
                    {
                        totalDieQtyIn = Integer.parseInt( line.substring( "DIES =".length() ).trim() );
                        //System.out.println("totalDieQtyIn = " + totalDieQtyIn);
                    }
                    if ( line.indexOf("Good Die") != -1 )
                    {
                        int passIdx = line.indexOf("Pass");
                        goodDieQtyIn = Integer.parseInt(line.substring( passIdx-7, passIdx-1 ).trim() ) ;
                        //System.out.println("goodDieQtyIn = " + goodDieQtyIn);
                    }
                }
            }

            if( lotNo != null && deviceName != null && waferNo > 0 && waferNo < 26 )
            {
                sortBinReport.setWaferID( waferNo +"" );
                sortBinReport.setGoodDieQtyIn( goodDieQtyIn );
                sortBinReport.setCustProduct( deviceName );
                sortBinReport.setProbeQtyIn( totalDieQtyIn );
                sortBinReport.setLotId( lotNo );
                sortBinReport.setFabLotNumber( lotNo );
                sortBinReport.setRejectedQtyIn( totalDieQtyIn - goodDieQtyIn );
                sortBinReport.setShipYield( (goodDieQtyIn/totalDieQtyIn ) +"" );

                sortlotbinList.add(sortBinReport);
            }
            bReader.close();
            bReader = null;
            line = null;
        }
        catch ( Exception e )
        {
            System.out.println( "Exception while parsing SiTime Sort Bin information \n" + e + "\n" );
            throw e;
        }
        finally
        {
            if ( bReader != null )
            {
                try
                {
                    bReader.close();
                }
                catch ( IOException ignore )
                {
                }
            }
        }
        return sortlotbinList;
    } // end of prase sortLot bin report method

    private void getSortBinDetails(ArrayList sortBinList )  throws Exception
    {
        if ( sortBinList == null || sortBinList.size() == 0 )
        {
           log( "No Sort Bin Lots when the List is Empty");
           return;
        }
        FabSortLot sortbinReport  = null;
        String partNumber                = null;
        String lotNumber                 = null;
        String waferId                   = null;
        FabSortLot sortBinTotalLot       = null;
        HashMap waferIdMap = new HashMap();
        try
        {
            Iterator iterator = sortBinList.iterator();

            while ( iterator.hasNext() )
            {
                sortbinReport = ( FabSortLot )iterator.next() ;

                lotNumber  = sortbinReport.getLotId();
                waferId    = sortbinReport.getWaferID();
                partNumber = sortbinReport.getCustProduct();

                if ( partNumber != null && lotNumber != null && waferId != null )
                {
                    sortBinTotalLot = (FabSortLot) m_sortTotalMap.get( partNumber + lotNumber);

                    if ( sortBinTotalLot == null )
                    {
                        sortBinTotalLot = new FabSortLot( VENDOR_NAME_SITIME, LOCATION_TYPE_SORT );
                        m_sortTotalMap.put( partNumber + lotNumber  , sortBinTotalLot );
                    }

                    int m_totalProbeQty         = 0;
                    int m_totalPassQty          = 0;
                    int m_waferQtyIn            = 0;
                    if ( sortBinTotalLot.getQtyIn() != null )
                    {
                       try
                       {
                           m_waferQtyIn = Integer.parseInt( sortBinTotalLot.getQtyIn() );
                       }
                       catch ( NumberFormatException ignore )
                       {
                       }

                       m_totalPassQty = sortBinTotalLot.getTotalgoodDieQtyIn();
                       m_totalProbeQty = sortBinTotalLot.getTotalprobeQtyIn();

                       if ( !waferIdMap.containsKey( partNumber + lotNumber + waferId ) )
                       {
                           waferIdMap.put( partNumber + lotNumber+waferId, waferId );
                            m_waferQtyIn += 1;

                            m_totalPassQty += sortbinReport.getGoodDieQtyIn();
                            m_totalProbeQty += sortbinReport.getProbeQtyIn();
                       }
                    }
                    else
                    {
                        if ( !waferIdMap.containsKey( partNumber + lotNumber+waferId ) )
                        {
                            waferIdMap.put( partNumber + lotNumber+waferId, waferId );
                            m_waferQtyIn = 1;
                            m_totalPassQty = sortbinReport.getGoodDieQtyIn();
                            m_totalProbeQty = sortbinReport.getProbeQtyIn();
                        }
                    }

                    sortBinTotalLot.setQtyIn( m_waferQtyIn+"");
                    sortBinTotalLot.setTotalgoodDieQtyIn( m_totalPassQty);
                    sortBinTotalLot.setTotalprobeQtyIn( m_totalProbeQty );
                }
            }
        }
        catch(Exception e )
        {
            throw new ScalarException("Exception occured while parsing the Sort Bin Inforamtion" +e );
        }
    }

    private void getSortBinDataMap(ArrayList sortBinList) throws Exception
    {
        String partNumber                = null;
        String lotNumber                 = null;
        String waferId                   = null;
        FabSortLot sortBinLot            = null;
        FabSortLot sortbinReport         = null;
        try
        {
            Iterator iterator = sortBinList.iterator();

            while ( iterator.hasNext() )
            {
                sortbinReport = ( FabSortLot )iterator.next() ;

                lotNumber  = sortbinReport.getLotId();
                waferId    = sortbinReport.getWaferID();
                partNumber = sortbinReport.getCustProduct();

                if ( partNumber != null && lotNumber != null && waferId != null )
                {
                    sortBinLot = ( FabSortLot ) m_sortBinDataMap.get( partNumber + lotNumber + waferId );

                    if ( sortBinLot == null )
                    {
                        sortBinLot = new FabSortLot( VENDOR_NAME_SITIME , LOCATION_TYPE_SORT );
                        m_sortBinDataMap.put( partNumber + lotNumber + waferId , sortBinLot );
                    }

                    sortBinLot.setCustProduct( partNumber );
                    sortBinLot.setLotId( lotNumber );
                    sortBinLot.setWaferID( waferId );
                    // WAFER QTY IN Always Same(total wafers) ,But For Each every Wafer update the Wafer Qty, the the WaferQty
                    sortBinLot.setQtyIn( 1 +"" );
                    sortBinLot.setDateIn( sortbinReport.getDateIn() );
                    sortBinLot.setTotalgoodDieQtyIn( sortbinReport.getGoodDieQtyIn() );
                    sortBinLot.setTotalprobeQtyIn(sortbinReport.getProbeQtyIn() );
                    sortBinLot.setGoodDieQtyIn(sortbinReport.getGoodDieQtyIn());
                    sortBinLot.setRejectedQtyIn(sortbinReport.getRejectedQtyIn());
                    sortBinLot.setShipYield(sortbinReport.getShipYield()+"");
                    sortBinLot.setTotalYield( 0 ); // if sets as 0, in the PROC Yield Calculating (INQTY *100.00/OUTQTY)
                    sortBinLot.setBinNumber( "Bin1");
               }
            }
        }
        catch(Exception e )
        {
            throw new ScalarException("Exception occured while parsing the Sort Bin Inforamtion" +e );
        }     
    }


    private void log( String message )
    {
        if ( message == null ) return;

        if ( m_parserLogger != null )
        {
            m_parserLogger.logDebug( message + LINE_SEPARATOR );
        }
        else
        {
            System.out.println( message );
        }
    } // end of log method
}

